﻿using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Collections.Generic;
using SPOnlineDevelopTool.Model;
using Microsoft.SharePoint.Publishing.WebControls;
using System.Text;
using SPOnlineDevelopTool.Utilities;
using Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.Utilities;
using System.Linq;
using System.IO;
using System.Xml.Serialization;

namespace SPOnlineDevelopTool.SPOnlineDevelopTool
{
    [ToolboxItemAttribute(false)]
    public class SPOnlineDevelopTool : Microsoft.SharePoint.WebPartPages.WebPart
    {
        #region 私有字段
        // 当更改可视 Web 部件项目项时，Visual Studio 可能会自动更新此路径。
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/SPOnlineDevelopTool/SPOnlineDevelopTool/SPOnlineDevelopToolUserControl.ascx";
        private const string _editScript = @"~/_layouts/SPOnlineDevelopTool/Script/ace-builds-master/src/ace.js";
        private const string _editStyle = @"~/_layouts/SPOnlineDevelopTool/Script/ace-builds-master/MyEditor.css";
        private const string _myEditScript = @"~/_layouts/SPOnlineDevelopTool/Script/ace-builds-master/MyEditor.js";
        private const string _spServicesScript = @"~/_layouts/SPOnlineDevelopTool/Script/jquery.SPServices-2013.01.min.js";
        private const string _embeddedInScriptsConfigPath = @"~/_layouts/SPOnlineDevelopTool/Configs/EmbeddedInScripts.xml";
        private HiddenField hfHtml;
        private List<EmbeddedInScripts> xmlConfigLst = null;
        private CheckBoxList rblScripts;
        private Label lblMessage;
        private bool IsSystemAdminEdit = false; 
        #endregion

        protected override void RenderWebPart(HtmlTextWriter output)
        {
            RenderChildren(output);
        }
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            //必须是系统管理员以及使用Chrome浏览器访问
            if (IsSystemAdminEdit && BrowserHelper.IsChromeAccess())
            {
                base.Render(writer);
                CreateLst();
                StringBuilder sb = new StringBuilder();
                sb.AppendLine(@"<link rel=""stylesheet"" href=""" + _editStyle + @""" type=""text/css"" />");
                sb.AppendLine(@"<script type=""text/javascript"" src=""" + _editScript + @"""></script>");
                sb.AppendLine("<pre id=\"editor\"></pre>");
                sb.AppendLine(@"<script type=""text/javascript"">var hfHtml=$('#" + hfHtml.ClientID + "');</script>");
                sb.AppendLine(@"<input type=""hidden"" id=""hfHtmlID"" value=""" + CodeID + @""" />");
                sb.AppendLine(@"<script type=""text/javascript"" src=""" + _myEditScript + @"""></script>");
                writer.Write(sb.ToString());
            }
            else
            {
                writer.Write(LstEmbeddedInScriptsResourse);
                base.Render(writer);
            }
        }

        private void CreateLst()
        {
            var list = new List<SPListInfo>()
            {
                new SPListInfo()
                {
                    ListDescription="前端代码库",
                    ListName="代码库",
                    SPType=SPListTemplateType.GenericList,
                    AddFieldAsXmls=new string[]{@"<Field Type=""String"" DisplayName=""代码"" EnforceUniqueValues=""FALSE"" Indexed=""FALSE""  StaticName=""Code"" Name=""Code"" />",@"<Field Type=""String"" DisplayName=""代码编号"" StaticName=""CodeID"" EnforceUniqueValues=""FALSE"" Indexed=""FALSE"" Name=""CodeID"" />"},
                }
            };
            CreateListByListInfo(SPContext.Current.Site.RootWeb, list);
        }

        public static void CreateListByListInfo(SPWeb currentWeb, List<SPListInfo> lst)
        {
            try
            {
                Guid SiteId = currentWeb.Site.ID;
                Guid WebId = currentWeb.ID;

                bool IsUnsafeEnabledForSite = false;
                bool IsUnsafeEnabledForWeb = false;
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    using (SPSite site = new SPSite(SiteId))
                    {
                        using (SPWeb web = site.OpenWeb(WebId))
                        {
                            if (site.AllowUnsafeUpdates)
                                IsUnsafeEnabledForSite = true;
                            else
                                site.AllowUnsafeUpdates = true;

                            if (web.AllowUnsafeUpdates)
                                IsUnsafeEnabledForSite = true;
                            else
                                web.AllowUnsafeUpdates = true;
                            foreach (var item in lst)
                            {
                                SPList list = web.Lists.TryGetList(item.ListName);
                                if (list == null)
                                {
                                    Guid id = web.Lists.Add(item.ListName, item.ListDescription, item.SPType);
                                    list = web.Lists[id];
                                    if (item.AddFieldAsXmls != null && item.AddFieldAsXmls.Length > 0)
                                    {
                                        foreach (var str in item.AddFieldAsXmls)
                                        {
                                            list.Fields.AddFieldAsXml(str, true, SPAddFieldOptions.Default);
                                        }
                                    }
                                    list.EnableVersioning = true;
                                    list.EnableMinorVersions = true;
                                    list.Update();
                                    web.Update();
                                }
                            }
                            if (!IsUnsafeEnabledForWeb)
                                web.AllowUnsafeUpdates = false;

                            if (!IsUnsafeEnabledForSite)
                                site.AllowUnsafeUpdates = false;
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                //TODO:错误消息
            }
        }


        protected override void CreateChildControls()
        {
            //当前页面必须为编辑状态并且当前账户为系统帐户
            IsSystemAdminEdit = SPHelper.IsInEditMode(this.Page) && (SPContext.Current.Web.CurrentUser.ID == SPContext.Current.Site.SystemAccount.ID);
            if (IsSystemAdminEdit)
            {
                lblMessage = new Label()
                {

                };
                Controls.Add(lblMessage);

                hfHtml = new HiddenField()
                {
                    ID = "hfHtml"
                };
                if (!string.IsNullOrEmpty(Html))
                    hfHtml.Value = Html;
                Controls.Add(hfHtml);

                //chkIsAddUserProfileScript = new CheckBox()
                //{
                //    ID = "chkIsAddUserProfileScript",
                //    Checked = IsAddSP_UserProfiles,
                //    Text = "是否加载SP.UserProfiles.js[仅支持SharePoint 2013]"
                //};
                //Controls.Add(chkIsAddUserProfileScript);
                LoadScriptLst();
                rblScripts = new CheckBoxList()
                {
                    ID = "rblScripts",
                    DataTextField = "DisplayText",
                    DataValueField = "ID"
                };
                rblScripts.DataSource = xmlConfigLst;
                rblScripts.DataBind();
                if (LstEmbeddedInScriptsResourseIds != null && LstEmbeddedInScriptsResourseIds.Length > 0)
                {
                    foreach (ListItem item in rblScripts.Items)
                    {
                        if (LstEmbeddedInScriptsResourseIds.Contains(item.Value))
                            item.Selected = true;
                    }
                }
                else
                {
                    lblMessage.Text = "LstEmbeddedInScripts为0";
                }
                Controls.Add(rblScripts);

                Button btnSubmit = new Button()
                {
                    Text = "保存",
                    OnClientClick = "return beforeSubmit()",
                };
                btnSubmit.Click += new System.EventHandler(btnSubmit_Click);
                Controls.Add(btnSubmit);


            }
            else
            {
                SPOnlineDevelopToolUserControl control = (SPOnlineDevelopToolUserControl)Page.LoadControl(_ascxPath);
                control.Html = Html;
                Controls.Add(control);
            }
        }

        private void LoadScriptLst()
        {
            var scriptConfigPath = this.Page.Server.MapPath(_embeddedInScriptsConfigPath);
            if (File.Exists(scriptConfigPath))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(List<EmbeddedInScripts>));
                StreamReader reader = File.OpenText(scriptConfigPath);
                xmlConfigLst = (List<EmbeddedInScripts>)serializer.Deserialize(reader);
                reader.Close();
            }
            else
            {
                xmlConfigLst = GetDefaultEmScriptsLst();
                XmlSerializer ser = new XmlSerializer(typeof(List<EmbeddedInScripts>));
                StreamWriter sw = new StreamWriter(scriptConfigPath);
                ser.Serialize(sw, xmlConfigLst);
                sw.Close();
            }
        }

        private static List<EmbeddedInScripts> GetDefaultEmScriptsLst()
        {
            List<EmbeddedInScripts> lst = new List<EmbeddedInScripts>()
                    {
                        new EmbeddedInScripts()
                        {
                            DisplayText="ACE编辑器",
                            ID=Guid.NewGuid().ToString("N"),
                            LstScript=new List<ScriptInfo>()
                            {
                                new ScriptInfo()
                                {
                                    ScriptType=ScriptType.Style,
                                    Url="/_layouts/ace-builds-master/MyEditor.css"
                                },
                                 new ScriptInfo()
                                {
                                    ScriptType=ScriptType.Script,
                                    Url="/_layouts/ace-builds-master/src/ace.js"
                                }
                                ,
                                 new ScriptInfo()
                                {
                                    ScriptType=ScriptType.Script,
                                    Url="/_layouts/ace-builds-master/MyEditor.js"
                                }
                            },
                        },
                        new EmbeddedInScripts()
                        {
                            DisplayText="jquery.SPServices",
                            ID=Guid.NewGuid().ToString("N"),
                            LstScript=new List<ScriptInfo>()
                            {
                                new ScriptInfo()
                                {
                                    ScriptType=ScriptType.Script,
                                    Url="/_layouts/FCS_Script/jquery.SPServices-2013.01.min.js"
                                }
                            },
                        },
                    };
            return lst;
        }

        void btnSubmit_Click(object sender, System.EventArgs e)
        {
            lblMessage.Text = "<br>";
            lblMessage.Text += "配置数：" + xmlConfigLst.Count + "<br>";
            if (xmlConfigLst == null || xmlConfigLst.Count == 0) LoadScriptLst();

            this.Html = hfHtml.Value;

            LstEmbeddedInScriptsResourse = string.Empty;

            foreach (ListItem item in rblScripts.Items)
            {
                if (item.Selected)
                {
                    lblMessage.Text += item.Text + ";";
                    var sc = xmlConfigLst.FirstOrDefault(p => p.ID == item.Value);
                    var sb = new StringBuilder();
                    foreach (var itemSc in sc.LstScript)
                    {
                        switch (itemSc.ScriptType)
                        {
                            case ScriptType.Style:
                                sb.AppendLine(@"<link rel=""stylesheet"" href=""" + itemSc.Url + @""" type=""text/css"" />");
                                break;
                            case ScriptType.Script:
                                sb.AppendLine(@"<script type=""text/javascript"" src=""" + itemSc.Url + @"""></script>");
                                break;
                            default:
                                break;
                        }
                        LstEmbeddedInScriptsResourseIds += item.Value + ";";
                    }
                    LstEmbeddedInScriptsResourse = sb.ToString();
                }
            }
            try
            {
                this.SaveProperties = true;
            }
            catch (Exception ex)
            {
                this.ToolTip = ex.ToString();
                lblMessage.Text += "<br>" + ex.ToString();
            }
        }

        [Browsable(true)]
        [WebPartStorage(Storage.Shared)]
        [Category("其他")]
        [FriendlyName("Html")]
        public string Html { get; set; }

        [Browsable(true)]
        [WebPartStorage(Storage.Shared)]
        [Category("其他")]
        [FriendlyName("HtmlTitle")]
        public string HtmlTitle { get; set; }

        private string _codeID;
        [Browsable(true)]
        [WebPartStorage(Storage.Shared)]
        [Category("其他")]
        [ReadOnly(true)]
        [FriendlyName("ID")]
        public string CodeID
        {
            get
            {
                if (string.IsNullOrEmpty(_codeID))
                    this.CodeID = Guid.NewGuid().ToString();
                return _codeID;
            }
            set { _codeID = value; }
        }
        [Browsable(true)]
        [WebPartStorage(Storage.Shared)]
        [Category("其他")]
        [ReadOnly(true)]
        [FriendlyName("是否加载SP.UserProfiles")]
        public bool IsAddSP_UserProfiles { get; set; }

        [Browsable(true)]
        [WebPartStorage(Storage.Shared)]
        [Category("其他")]
        [ReadOnly(true)]
        [FriendlyName("加载的脚本资源")]
        public string LstEmbeddedInScriptsResourse { get; set; }

        [Browsable(true)]
        [WebPartStorage(Storage.Shared)]
        [Category("其他")]
        [ReadOnly(true)]
        [FriendlyName("加载的脚本资源IDs")]
        public string LstEmbeddedInScriptsResourseIds { get; set; }
    }
}
